"""
AI Agent Pro - 搜索工具
"""

import asyncio
import json
import re
from typing import Any, Dict, List, Optional
from urllib.parse import quote_plus

import aiohttp
from bs4 import BeautifulSoup

from app.core.config import get_settings
from app.core.logging import get_logger
from app.tools.base import BaseTool, ToolResult, ToolSchema, ToolParameter, ToolType

logger = get_logger(__name__)
settings = get_settings()


class WebSearchTool(BaseTool):
    """网络搜索工具"""
    
    def get_schema(self) -> ToolSchema:
        return ToolSchema(
            name="web_search",
            description="在互联网上搜索信息，返回相关的搜索结果",
            tool_type=ToolType.SEARCH,
            parameters=[
                ToolParameter(
                    name="query",
                    type="string",
                    description="搜索关键词或问题",
                    required=True
                ),
                ToolParameter(
                    name="num_results",
                    type="integer",
                    description="返回结果数量",
                    required=False,
                    default=5,
                    min_value=1,
                    max_value=20
                ),
                ToolParameter(
                    name="language",
                    type="string",
                    description="搜索语言",
                    required=False,
                    default="zh-CN",
                    enum=["zh-CN", "en-US", "ja", "ko"]
                ),
                ToolParameter(
                    name="safe_search",
                    type="boolean",
                    description="是否启用安全搜索",
                    required=False,
                    default=True
                )
            ],
            examples=[
                {
                    "query": "人工智能最新发展",
                    "num_results": 5,
                    "language": "zh-CN"
                },
                {
                    "query": "Python programming tutorial",
                    "num_results": 3,
                    "language": "en-US"
                }
            ],
            tags=["搜索", "网络", "信息检索"],
            timeout=30
        )
    
    async def _execute(self, **kwargs) -> ToolResult:
        query = kwargs.get("query")
        num_results = kwargs.get("num_results", 5)
        language = kwargs.get("language", "zh-CN")
        safe_search = kwargs.get("safe_search", True)
        
        try:
            # 尝试使用Google自定义搜索API
            if settings.google_search_api_key and settings.google_search_engine_id:
                results = await self._google_search(query, num_results, language, safe_search)
            else:
                # 回退到模拟搜索或其他方法
                results = await self._fallback_search(query, num_results, language)
            
            return ToolResult(
                success=True,
                data={
                    "query": query,
                    "results": results,
                    "total_results": len(results)
                },
                metadata={
                    "search_engine": "google" if settings.google_search_api_key else "fallback",
                    "language": language,
                    "safe_search": safe_search
                }
            )
            
        except Exception as e:
            logger.error(f"网络搜索失败: {str(e)}")
            return ToolResult(
                success=False,
                error=f"搜索失败: {str(e)}"
            )
    
    async def _google_search(
        self,
        query: str,
        num_results: int,
        language: str,
        safe_search: bool
    ) -> List[Dict[str, Any]]:
        """使用Google自定义搜索API"""
        url = "https://www.googleapis.com/customsearch/v1"
        
        params = {
            "key": settings.google_search_api_key,
            "cx": settings.google_search_engine_id,
            "q": query,
            "num": min(num_results, 10),  # Google API 最多返回10个结果
            "hl": language.split("-")[0],
            "safe": "active" if safe_search else "off"
        }
        
        async with aiohttp.ClientSession() as session:
            async with session.get(url, params=params) as response:
                if response.status == 200:
                    data = await response.json()
                    return self._parse_google_results(data)
                else:
                    error_text = await response.text()
                    raise Exception(f"Google搜索API错误 ({response.status}): {error_text}")
    
    def _parse_google_results(self, data: Dict[str, Any]) -> List[Dict[str, Any]]:
        """解析Google搜索结果"""
        results = []
        
        for item in data.get("items", []):
            result = {
                "title": item.get("title", ""),
                "url": item.get("link", ""),
                "snippet": item.get("snippet", ""),
                "display_link": item.get("displayLink", ""),
                "formatted_url": item.get("formattedUrl", "")
            }
            
            # 提取图片（如果有）
            if "pagemap" in item and "cse_image" in item["pagemap"]:
                result["image"] = item["pagemap"]["cse_image"][0].get("src", "")
            
            results.append(result)
        
        return results
    
    async def _fallback_search(
        self,
        query: str,
        num_results: int,
        language: str
    ) -> List[Dict[str, Any]]:
        """回退搜索方法（模拟或使用其他服务）"""
        # 这里可以实现其他搜索方法，比如：
        # 1. 使用DuckDuckGo
        # 2. 使用Bing API
        # 3. 模拟搜索结果
        
        # 示例：模拟搜索结果
        mock_results = [
            {
                "title": f"关于 '{query}' 的搜索结果 1",
                "url": "https://example.com/result1",
                "snippet": f"这是关于 {query} 的详细信息。包含了相关的背景知识和最新发展动态。",
                "display_link": "example.com",
                "formatted_url": "https://example.com/result1"
            },
            {
                "title": f"'{query}' 深度分析",
                "url": "https://research.example.com/analysis",
                "snippet": f"深度分析 {query} 的各个方面，提供专业的见解和数据支持。",
                "display_link": "research.example.com",
                "formatted_url": "https://research.example.com/analysis"
            },
            {
                "title": f"{query} - 最新资讯",
                "url": "https://news.example.com/latest",
                "snippet": f"最新关于 {query} 的新闻资讯和行业动态，及时更新的信息。",
                "display_link": "news.example.com",
                "formatted_url": "https://news.example.com/latest"
            }
        ]
        
        # 返回指定数量的结果
        return mock_results[:num_results]


class DocumentSearchTool(BaseTool):
    """文档搜索工具"""
    
    def get_schema(self) -> ToolSchema:
        return ToolSchema(
            name="document_search",
            description="在知识库或文档集合中搜索相关信息",
            tool_type=ToolType.SEARCH,
            parameters=[
                ToolParameter(
                    name="query",
                    type="string",
                    description="搜索查询",
                    required=True
                ),
                ToolParameter(
                    name="collection",
                    type="string",
                    description="文档集合名称",
                    required=False,
                    default="default"
                ),
                ToolParameter(
                    name="limit",
                    type="integer",
                    description="返回结果数量限制",
                    required=False,
                    default=10,
                    min_value=1,
                    max_value=50
                ),
                ToolParameter(
                    name="similarity_threshold",
                    type="number",
                    description="相似度阈值",
                    required=False,
                    default=0.7,
                    min_value=0.0,
                    max_value=1.0
                )
            ],
            examples=[
                {
                    "query": "机器学习算法",
                    "collection": "ai_documents",
                    "limit": 5
                }
            ],
            tags=["搜索", "文档", "知识库"],
            timeout=15
        )
    
    async def _execute(self, **kwargs) -> ToolResult:
        query = kwargs.get("query")
        collection = kwargs.get("collection", "default")
        limit = kwargs.get("limit", 10)
        similarity_threshold = kwargs.get("similarity_threshold", 0.7)
        
        try:
            # 这里应该连接到实际的向量数据库或文档搜索引擎
            # 比如 Qdrant, Pinecone, Elasticsearch 等
            
            # 模拟文档搜索结果
            mock_documents = [
                {
                    "id": f"doc_001",
                    "title": f"关于'{query}'的技术文档",
                    "content": f"这是一篇详细介绍{query}的技术文档，包含了理论基础和实践应用。",
                    "source": "internal_docs",
                    "created_at": "2024-01-15",
                    "similarity_score": 0.95,
                    "metadata": {
                        "author": "AI研究团队",
                        "category": "技术文档",
                        "tags": ["AI", "技术"]
                    }
                },
                {
                    "id": f"doc_002",
                    "title": f"{query}实践指南",
                    "content": f"实用的{query}实践指南，提供步骤化的操作说明和最佳实践。",
                    "source": "knowledge_base",
                    "created_at": "2024-01-10",
                    "similarity_score": 0.88,
                    "metadata": {
                        "author": "产品团队",
                        "category": "指南",
                        "tags": ["实践", "指南"]
                    }
                }
            ]
            
            # 过滤低于阈值的结果
            filtered_docs = [
                doc for doc in mock_documents
                if doc["similarity_score"] >= similarity_threshold
            ]
            
            # 限制结果数量
            results = filtered_docs[:limit]
            
            return ToolResult(
                success=True,
                data={
                    "query": query,
                    "documents": results,
                    "total_found": len(results),
                    "collection": collection
                },
                metadata={
                    "similarity_threshold": similarity_threshold,
                    "search_method": "vector_similarity"
                }
            )
            
        except Exception as e:
            logger.error(f"文档搜索失败: {str(e)}")
            return ToolResult(
                success=False,
                error=f"文档搜索失败: {str(e)}"
            )


class ImageSearchTool(BaseTool):
    """图片搜索工具"""
    
    def get_schema(self) -> ToolSchema:
        return ToolSchema(
            name="image_search",
            description="搜索相关图片",
            tool_type=ToolType.SEARCH,
            parameters=[
                ToolParameter(
                    name="query",
                    type="string",
                    description="图片搜索关键词",
                    required=True
                ),
                ToolParameter(
                    name="num_images",
                    type="integer",
                    description="返回图片数量",
                    required=False,
                    default=5,
                    min_value=1,
                    max_value=20
                ),
                ToolParameter(
                    name="image_size",
                    type="string",
                    description="图片尺寸偏好",
                    required=False,
                    default="medium",
                    enum=["small", "medium", "large", "xlarge"]
                ),
                ToolParameter(
                    name="image_type",
                    type="string",
                    description="图片类型",
                    required=False,
                    default="photo",
                    enum=["photo", "clipart", "lineart", "face"]
                )
            ],
            examples=[
                {
                    "query": "美丽的日出",
                    "num_images": 3,
                    "image_size": "large"
                }
            ],
            tags=["搜索", "图片", "视觉"],
            timeout=20
        )
    
    async def _execute(self, **kwargs) -> ToolResult:
        query = kwargs.get("query")
        num_images = kwargs.get("num_images", 5)
        image_size = kwargs.get("image_size", "medium")
        image_type = kwargs.get("image_type", "photo")
        
        try:
            # 模拟图片搜索结果
            mock_images = []
            
            for i in range(num_images):
                mock_images.append({
                    "url": f"https://example.com/image_{i+1}.jpg",
                    "thumbnail_url": f"https://example.com/thumb_{i+1}.jpg",
                    "title": f"{query} - 图片 {i+1}",
                    "description": f"这是关于'{query}'的高质量图片",
                    "width": 800 if image_size == "large" else 400,
                    "height": 600 if image_size == "large" else 300,
                    "file_size": f"{200 + i*50}KB",
                    "source": f"source_{i+1}.com",
                    "metadata": {
                        "image_type": image_type,
                        "color_dominant": ["#FF6B6B", "#4ECDC4", "#45B7D1"][i % 3]
                    }
                })
            
            return ToolResult(
                success=True,
                data={
                    "query": query,
                    "images": mock_images,
                    "total_found": len(mock_images)
                },
                metadata={
                    "image_size": image_size,
                    "image_type": image_type,
                    "search_engine": "mock"
                }
            )
            
        except Exception as e:
            logger.error(f"图片搜索失败: {str(e)}")
            return ToolResult(
                success=False,
                error=f"图片搜索失败: {str(e)}"
            )


# 注册工具的便捷函数
def register_search_tools():
    """注册所有搜索工具"""
    from app.tools.manager import tool_manager
    
    tools = [
        WebSearchTool(),
        DocumentSearchTool(),
        ImageSearchTool()
    ]
    
    for tool in tools:
        tool_manager.register_tool(tool)
    
    logger.info("搜索工具注册完成")


# 导出
__all__ = [
    "WebSearchTool",
    "DocumentSearchTool", 
    "ImageSearchTool",
    "register_search_tools",
]